﻿using ErrorOr;
using Gym.Application.Common.Interfaces;
using Gym.Domain.AdminAggregate;
using Gym.Domain.ParticipantAggregate;
using Gym.Domain.Profiles;
using Gym.Domain.TrainerAggregate;
using MediatR;
using Microsoft.VisualBasic;

namespace Gym.Application.Profiles.Commands.CreateProfile
{
    public class CreateProfileCommandHandler : IRequestHandler<CreateProfileCommand, ErrorOr<Guid>>
    {
        private readonly IAdminsRepository _adminsRepository;
        private readonly ITrainersRepository _trainersRepository;
        private readonly IParticipantsRepository _participantsRepository;

        public CreateProfileCommandHandler(
            IAdminsRepository adminsRepository,
            ITrainersRepository trainersRepository,
            IParticipantsRepository participantsRepository)
        {
            _adminsRepository = adminsRepository;
            _trainersRepository = trainersRepository;
            _participantsRepository = participantsRepository;
        }

        public async Task<ErrorOr<Guid>> Handle(CreateProfileCommand command, CancellationToken cancellationToken)
        {
            return command.ProfileType.Name switch
            {
                nameof(ProfileType.Admin) => await CreateAdminAsync(command.UserId),
                nameof(ProfileType.Trainer) => await CreateTrainerAsync(command.UserId),
                nameof(ProfileType.Participant) => await CreateParticipantAsync(command.UserId),
                _ => throw new InvalidOperationException()
            };
        }

        private async Task<ErrorOr<Guid>> CreateParticipantAsync(Guid userId)
        {
            if (await _participantsRepository.GetProfileByUserIdAsync(userId) is not null)
                return Error.Conflict("用户已有会员信息");
            
            var participant = new Participant(userId);
            await _participantsRepository.AddParticipantAsync(participant);
            return participant.Id;
        }

        private async Task<ErrorOr<Guid>> CreateTrainerAsync(Guid userId)
        {
            if (await _trainersRepository.GetProfileByUserIdAsync(userId) is not null)
            {
                return Error.Conflict("用户已有教练信息");
            }

            var trainer = new Trainer(userId);
            await _trainersRepository.AddTrainerAsync(trainer);
            return trainer.Id;
        }

        private async Task<ErrorOr<Guid>> CreateAdminAsync(Guid userId)
        {
            if (await _adminsRepository.GetProfileByUserIdAsync(userId) is not null)
            {
                return Error.Conflict("用户已有管理员信息");
            }

            var admin = new Admin(userId);
            await _adminsRepository.AddAdminAsync(admin);
            return admin.Id;
        }
    }
}
